/* << fastinsert report library >> PdfPage.cpp Oct 31, 2010
 *
 * 	http://code.google.com/p/libfir
 *
 * Copyright (c) 2005 Pavlo Drobov (drobov.pavel@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#include "Debug.h"
#include "PdfPage.h"

namespace dasco
{
namespace report
{


PdfPage::PdfPage(const HPDF_Doc& pdf)
	:page(::HPDF_AddPage(pdf))
{
	::HPDF_Page_SetTextRenderingMode (page, HPDF_FILL);

	//default A4
	 setSize(mm2pixel(A4_WIDTH,RESOLUTION_DPI),mm2pixel(A4_HIGHT,RESOLUTION_DPI));
	 setResolution(RESOLUTION_DPI);
}


PdfPage::~PdfPage()
{
}


void PdfPage::setWidth(const float width)
{
	::HPDF_Page_SetWidth (page, width);
}

void PdfPage::setHeight(const float height)
{
	::HPDF_Page_SetHeight (page, height);
}

float PdfPage::getWidth() const
{
	return ::HPDF_Page_GetWidth(page);
}
float PdfPage::getHeight() const
{
	return ::HPDF_Page_GetHeight(page);
}


void PdfPage::setSize(const float width,const float height)
{
	setWidth(width);
	setHeight(height);
}

void PdfPage::setResolution(const float dpi)
{
	//::HPDF_Page_Concat (page, 72.0f / dpi, 0, 0, 72.0f / dpi, 0, 0);
}


void  PdfPage::setTextRenderingMode(const HPDF_TextRenderingMode textRenderingMode)
{
	::HPDF_Page_SetTextRenderingMode (page, textRenderingMode);
}


void  PdfPage::setFontAndSize(const HPDF_Font&  font,const float  size)
{
	::HPDF_Page_SetFontAndSize (page, font, size);
}

void PdfPage::beginText() const
{
	::HPDF_Page_BeginText(page);
}
void PdfPage::endText() const
{
	::HPDF_Page_EndText (page);
}

void PdfPage::renderText(const float x,const float y,const char* text,bool beginend)
{
	//HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
	//attr->fonts
	//HPDF_Font_TextWidth()

/*
	unsigned len = ::HPDF_Page_MeasureText (page, text,
	                        ::HPDF_Page_GetWidth(page), HPDF_FALSE, NULL);


	DEBUG_MSG("text: " << text);
	DEBUG_MSG("\t len: " << len);

	char bb[5];
	::snprintf(bb,sizeof(bb),"%u",len);
	for(char *r =bb; r-bb < sizeof(bb); r++)
	{
		if(*r == '\0') *r = ' ';
	}

	memcpy((void*)(text+3),bb,sizeof(bb));
*/
	if(beginend)
		beginText();
	::HPDF_Page_TextOut(page,x,y,text);
	if(beginend)
		endText();


}

void PdfPage::showText(const char* text)
{
	::HPDF_Page_ShowText (page, text);
}

void PdfPage::setTextMatrix(const matrix* m)
{
	::HPDF_Page_SetTextMatrix(page,m->a,m->b,m->c,m->d,m->srcX,m->srcY);
}


HPDF_Destination PdfPage::createDestination() const
{
	return ::HPDF_Page_CreateDestination (page);
}


void PdfPage::renderLine(const renderLinePx* pxLine)
{
	//  ::HPDF_Page_SetGrayFill (page, 0.0f);
	::HPDF_Page_SetGrayStroke(page, pxLine->gray);
	::HPDF_Page_SetLineWidth(page, pxLine->brushWidth);
	if (pxLine->dashFactor)
		::HPDF_Page_SetDash(page, pxLine->dashFactor, 1, 1);

	::HPDF_Page_MoveTo(page, pxLine->srcX, pxLine->srcY);
	::HPDF_Page_LineTo(page, pxLine->dstX, pxLine->dstY);
	::HPDF_Page_Stroke(page);

	//  ::HPDF_Page_SetGrayFill (page, 0);
	::HPDF_Page_SetGrayStroke(page, 0.0f);

}

void PdfPage::renderZebra(const renderZebraPx* pxZebra)
{
/*
//////// render rec for visio ZEBRA area, only for debug
	renderLinePx rec;
	rec.gray = 0.0f;
	rec.brushWidth = 1.0f;

	rec.srcX = pxZebra->srcX;
	rec.srcY = rec.dstY = pxZebra->srcY;
	rec.dstX = pxZebra->srcX +pxZebra->width;

	renderLine(&rec);

	rec.srcX= rec.dstX = pxZebra->srcX;
	rec.srcY = pxZebra->srcY;
	rec.dstY =  pxZebra->srcY +pxZebra->hight;

	renderLine(&rec);
///////////////////////////////////////////////////
*/
	renderLinePx pxLine;
	pxLine.gray = pxZebra->gray;
	pxLine.brushWidth = pxZebra->brushWidth;
	pxLine.dashFactor = pxZebra->dashFactor;


	for (pxLine.srcX = pxLine.dstX = pxZebra->srcX, pxLine.srcY = pxLine.dstY= pxZebra->srcY, pxLine.dstX += pxZebra->hight, pxLine.dstY += pxZebra->hight
			; pxLine.dstX > pxLine.srcX
			; pxLine.dstX -= pxZebra->step, pxLine.srcY += pxZebra->step)
	{
		//DEBUG_MSG(pxLine);
		renderLine(&pxLine);
	}

	for (pxLine.srcX = pxLine.dstX = pxZebra->srcX + pxZebra->step, pxLine.srcY = pxLine.dstY= pxZebra->srcY, pxLine.dstX += pxZebra->hight, pxLine.dstY += pxZebra->hight
			; pxLine.dstX <  pxZebra->srcX + pxZebra->width
			; pxLine.srcX += pxZebra->step , pxLine.dstX += pxZebra->step)
	{
		//DEBUG_MSG(pxLine);
		renderLine(&pxLine);
	}

	for (
			; pxLine.srcX <  pxZebra->srcX + pxZebra->width
			; pxLine.srcX += pxZebra->step , pxLine.dstY -= pxZebra->step)
	{
		//DEBUG_MSG(pxLine);
		renderLine(&pxLine);
	}
}





}} //end namespace dasco::report

